package com.googlecode.kipler.transformations;

import com.googlecode.kipler.syntax.concept.AtConcept;
import com.googlecode.kipler.syntax.concept.BooleanConcept;
import com.googlecode.kipler.syntax.concept.Bottom;
import com.googlecode.kipler.syntax.concept.CardinalityRestriction;
import com.googlecode.kipler.syntax.concept.Concept;
import com.googlecode.kipler.syntax.concept.ConceptName;
import com.googlecode.kipler.syntax.concept.ConceptVisitor;
import com.googlecode.kipler.syntax.concept.NaryBooleanConcept;
import com.googlecode.kipler.syntax.concept.Nominal;
import com.googlecode.kipler.syntax.concept.QualifiedNoRestriction;
import com.googlecode.kipler.syntax.concept.RoleQuantification;
import com.googlecode.kipler.syntax.concept.Top;

public class NominalReplacingVisitor implements ConceptVisitor {

	private Concept result;

	private String replaceBy, replaced;

	public NominalReplacingVisitor(String replaceBy, String replaced) {
		this.replaceBy = replaceBy;
		this.replaced = replaced;
	}

	public Concept getResult() {
		return result;
	}

	@Override
	public void visitAtConcept(AtConcept c) {
		result = c.copy();
		AtConcept lResult = (AtConcept) result;
		NominalReplacingVisitor replacer = new NominalReplacingVisitor(
				replaceBy, replaced);
		c.getConcept().accept(replacer);
		lResult.setConcept(replacer.getResult());
		if (lResult.getName().equals(replaced)) {
			lResult.setName(replaceBy);
		}
	}

	@Override
	public void visitBooleanConcept(BooleanConcept bd) {
		result = bd.copy();
		BooleanConcept lResult = (BooleanConcept) result;
		NominalReplacingVisitor replacer = new NominalReplacingVisitor(
				replaceBy, replaced);
		bd.getLhs().accept(replacer);
		lResult.setLhs(replacer.getResult());
		replacer = new NominalReplacingVisitor(replaceBy, replaced);
		bd.getRhs().accept(replacer);
		lResult.setRhs(replacer.getResult());
	}

	@Override
	public void visitCardinalityRestriction(CardinalityRestriction restriction) {
		// TODO Auto-generated method stub

	}

	@Override
	public void visitConceptName(ConceptName c) {
		result = c;
	}

	@Override
	public void visitNominal(Nominal nominal) {
		result = nominal;
		if (nominal.getName().equals(replaced)) {
			Nominal lResult = nominal.copy();
			lResult.setName(replaceBy);
			result = lResult;
		}
	}

	@Override
	public void visitQualifiedNoRestriction(QualifiedNoRestriction restriction) {
		// TODO Auto-generated method stub

	}

	@Override
	public void visitRoleQuantification(RoleQuantification restriction) {
		// TODO Auto-generated method stub

	}

	@Override
	public void visitBottom(Bottom bottom) {
		result = bottom;
	}

	@Override
	public void visitTop(Top top) {
		result = top;
	}

	@Override
	public void visitNaryBooleanConcept(NaryBooleanConcept bd) {
		NaryBooleanConcept result = new NaryBooleanConcept(bd.getConstructor());
		for (Concept c : bd.getOperands()) {
			NominalReplacingVisitor replacer = new NominalReplacingVisitor(
					replaceBy, replaced);
			c.accept(replacer);
			result.addOperand(replacer.getResult());
		}
		this.result = result;
	}

}
